﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using EkspSys.Network;

namespace EkspSys.network
{
    enum PckDirection
    {
        INGOING, OUTGOING
    };

    class Utils
    {
        private static Utils instance;

        private Utils()
        {
        }

        public static Utils Get()
        {
            if (instance == null)
                instance = new Utils();
            return instance;
        }

        private IPAddress[] localAddrs = Dns.GetHostAddresses(Dns.GetHostName());

        public bool IsLocal(IPAddress addr)
        {
            if (IPAddress.IsLoopback(addr))
                return true;
            return localAddrs.Contains(addr);
        }

        public Tuple<IPAddress, ushort, PckDirection> GetRemoteSide(Package pck)
        {
            bool localSrc = IsLocal(pck.srcAddr);
            bool localDest = IsLocal(pck.destAdr);

            if (localSrc && !localDest)
            {
                // Outgoing package
                return Tuple.Create(pck.destAdr, pck.destPort, PckDirection.OUTGOING);
            }
            else if (!localSrc && localDest)
            {
                // Ingoing package
                return Tuple.Create(pck.srcAddr, pck.srcPort, PckDirection.INGOING);
            }
            else if (localSrc && localDest)
            {
                // Internal package
                return null;
            }
            else
            {
                // Weird package
                return null;
            }
        }

        internal Tuple<IPAddress, ushort, PckDirection> GetLocalSide(Package pck)
        {
            bool localSrc = IsLocal(pck.srcAddr);
            bool localDest = IsLocal(pck.destAdr);

            if (localSrc && !localDest)
            {
                // Outgoing package
                return Tuple.Create(pck.srcAddr, pck.srcPort, PckDirection.OUTGOING);
            }
            else if (!localSrc && localDest)
            {
                // Ingoing package
                return Tuple.Create(pck.destAdr, pck.destPort, PckDirection.INGOING);
            }
            else if (localSrc && localDest)
            {
                // Internal package
                return null;
            }
            else
            {
                // Weird package
                return null;
            }
        }
    }
}
